package com.fanshuai.soring.boot.mvc;

import com.fanshuai.soring.boot.constants.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;

@Slf4j
public class MyHandlerMapping extends RequestMappingHandlerMapping {
    private HandlerMethod notFoundHandlerMethod = null;

    @Override
    public void afterPropertiesSet() {
        super.afterPropertiesSet();

        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {
            String notFoundUrl = "/notFound";
            if (entry.getKey().getPatternsCondition().getPatterns().contains(notFoundUrl)) {
                notFoundHandlerMethod = entry.getValue();
                log.info("set notFoundHandlerMethod={}", entry.getValue());
            }
        }
    }

    @Override
    protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> infos, String lookupPath, HttpServletRequest request) throws ServletException {
        String metricsHeader = request.getHeader("metrics");
        boolean noMatchWithoutMetrics = lookupPath.equals("/metrics") || StringUtils.isNotBlank(metricsHeader);

        if (!noMatchWithoutMetrics) {
            request.setAttribute(CommonConstants.ORIGINAL_URI, request.getRequestURI());
            return notFoundHandlerMethod;
        }
        return super.handleNoMatch(infos, lookupPath, request);
    }
}
